home *** CD-ROM | disk | FTP | other *** search
/ The Atari Compendium / The Atari Compendium (Toad Computers) (1994).iso / files / prgtools / mint / network / lattice / portlib.lzh / PORTLIB / MINT.C < prev    next >
Encoding:
C/C++ Source or Header  |  1994-07-01  |  2.9 KB  |  155 lines

  1. /*
  2.  *    int __mint_read  (int, void *, unsigned int);
  3.  *    int __mint_write (int, void *, unsigned int);
  4.  *
  5.  *    Q&D posix like read() and write(). They (should) return
  6.  *    EWOULDBLOCK for nonblocking mode and no data avail / no
  7.  *    space left. 
  8.  *
  9.  *    int __fork_and_exit();
  10.  *
  11.  *    This acts like 'if (fork()) exit();' with a nonblocking fork.
  12.  *    But unfortunately MiNT's fork() does block the parent until
  13.  *    child does exec() or exit(). So use fork_and_exit() as a temp.
  14.  *    workaround.
  15.  *
  16.  *    12/28/93, kay roemer <roemer@rbi.informatik.uni-frankfurt.de>
  17.  */
  18.  
  19. #include <unistd.h>
  20. #include <fcntl.h>
  21. #include <errno.h>
  22. #include <ioctl.h>
  23. #include <osbind.h>
  24. #include <mintbind.h>
  25. #include <setjmp.h>
  26. #include <signal.h>
  27.  
  28. #define UNLIMITED    1000000
  29.  
  30. int
  31. __check_nbio_read (int fd)
  32. {
  33.     unsigned long buf;
  34.     int s;
  35.  
  36.     if (Fcntl (fd, 0, F_GETFL) & O_NDELAY) {
  37.         s = Fcntl (fd, &buf, FIONREAD);
  38.         if (!s && buf < UNLIMITED) {
  39.             errno = EWOULDBLOCK;
  40.             return -1;
  41.         }
  42.     }
  43.     return 0;
  44. }
  45.  
  46. int
  47. __check_nbio_write (int fd)
  48. {
  49.     unsigned long buf;
  50.     int s;
  51.  
  52.     if (Fcntl (fd, 0, F_GETFL) & O_NDELAY) {
  53.         s = Fcntl (fd, &buf, FIONWRITE);
  54.         if (!s && buf < UNLIMITED) {
  55.             errno = EWOULDBLOCK;
  56.             return -1;
  57.         }
  58.     }
  59.     return 0;
  60. }
  61.  
  62. int
  63. __mint_read (int fd, void *buffer, unsigned int buflen)
  64. {
  65.     int r, s;
  66.     unsigned long buf;
  67.     extern int errno;
  68.  
  69.     r = Fread (fd, buflen, buffer);
  70.     if (r <= 0) {
  71.         if (r < 0) {
  72.             errno = -r;
  73.             return -1;
  74.         }
  75.         if (buflen && Fcntl (fd, 0, F_GETFL) & O_NDELAY) {
  76.             s = Fcntl (fd, &buf, FIONREAD);
  77.             if (!s && buf < UNLIMITED) {
  78.                 errno = EWOULDBLOCK;
  79.                 return -1;
  80.             }
  81.         }
  82.     }
  83.     return r;
  84. }
  85.  
  86. int
  87. __mint_write (int fd, void *buffer, unsigned int buflen)
  88. {
  89.     int r, s;
  90.     unsigned long buf;
  91.     extern int errno;
  92.  
  93.     r = Fwrite (fd, buflen, buffer);
  94.     if (r <= 0) {
  95.         if (r < 0) {
  96.             errno = -r;
  97.             return -1;
  98.         }
  99.         if (buflen && Fcntl (fd, 0, F_GETFL) & O_NDELAY) {
  100.             s = Fcntl (fd, &buf, FIONWRITE);
  101.             if (!s && buf < UNLIMITED) {
  102.                 errno = EWOULDBLOCK;
  103.                 return -1;
  104.             }
  105.         }
  106.     }
  107.     return r;
  108. }
  109.  
  110. static int fd_flags[32];
  111. static jmp_buf jmpbuf;
  112. static struct sigaction sas[32];
  113. static long sigmask;
  114.  
  115. static int
  116. child_proc (long pip)
  117. {
  118.     char buf;
  119.     int i;
  120.     
  121.     if (read (pip, &buf, 1)) exit (0);
  122.     close (pip);
  123.     for (i = 0; i < 32; ++i) {
  124.         if (fd_flags[i] >= 0)
  125.             fcntl (i, F_SETFD, fd_flags[i]);
  126.     }
  127.     for (i = 0; i < 32; ++i) {
  128.         sigaction (i, &sas[i], 0);
  129.     }
  130.     longjmp (jmpbuf, 1);
  131. }
  132.     
  133. int
  134. __fork_and_exit (void)
  135. {
  136.     static int i, pip[2];
  137.     extern int tfork (int (*)(long), long);
  138.  
  139.     if (pipe (pip) < 0) return -1;
  140.     sigmask = sigsetmask (~0L);
  141.     for (i = 0; i < 32; ++i) {
  142.         fd_flags[i] = fcntl (i, F_GETFD, 0);
  143.         fcntl (i, F_SETFD, i == pip[1] ? FD_CLOEXEC : 0);
  144.     }
  145.     for (i = 0; i < 32; ++i) {
  146.         sigaction (i, 0, &sas[i]);
  147.     }
  148.     if (!setjmp (jmpbuf)) {
  149.         tfork (child_proc, pip[0]);
  150.         exit (0);
  151.     }
  152.     sigsetmask (sigmask);
  153.     return 0;
  154. }
  155.